using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

using Conscript;
using Conscript.Runtime;

namespace DungeonOfDespair
{
    public class Enemies
        : List<Enemy>
    {
        private Room m_room;
        private ScriptManager m_scriptManager;
        private Player m_player;

        private EnemyType ParseEnemyType(String strEnemyType)
        {
            foreach (EnemyType enemyType in Enum.GetValues(typeof(EnemyType)))
                if (enemyType.ToString() == strEnemyType)
                    return enemyType;
            throw new Exception("Unknown enemy type '" + strEnemyType + "'.");
        }

        public Enemies(Room room)
        {
            m_room = room;
            m_scriptManager = m_room.Dungeon.ScriptManager;
            m_player = m_room.Dungeon.Player;
        }

        public void Load(AssociativeArray associativeArrayEnemies)
        {
            // process enemies
            int iEnemyIndex = 0;
            while (true)
            {
                // enemy nodes in format EnemyNNN
                String strEnemyKey = "Enemy" + iEnemyIndex;

                // stop if no more enemies found
                if (!associativeArrayEnemies.ContainsKey(strEnemyKey))
                    break;

                AssociativeArray associativeArrayEnemy
                    = (AssociativeArray)associativeArrayEnemies[strEnemyKey];

                // get enemy type and qty
                String strEnemyType = (String)associativeArrayEnemy["Type"];
                EnemyType enemyType = ParseEnemyType(strEnemyType);
                int iQuantity = (int)associativeArrayEnemy["Quantity"];

                // spawn enemies
                while (iQuantity-- > 0)
                    this.Add(new Enemy(this, enemyType));

                ++iEnemyIndex;
            }
        }

        public void Reset()
        {
            Random random = new Random();
            foreach (Enemy enemy in this)
                enemy.Reset();
        }

        public void Update()
        {
            // sort by y position
            this.Sort(
                delegate(Enemy enemy1, Enemy enemy2)
                {
                    return enemy1.Y.CompareTo(enemy2.Y);
                });

            // update
            foreach (Enemy enemy in this)
            {
                if (!enemy.Active) continue;

                enemy.Update();

                // collision with player
                if (enemy.CollidingWith(m_player))
                    m_player.Health = Math.Max(0, m_player.Health - 1);
            }
        }

        public void Draw(Graphics graphics, bool bAfterPlayer)
        {
            if (bAfterPlayer)
            {
                foreach (Enemy enemy in this)
                    if  (enemy.Active && enemy.Y >= m_player.Y)
                        enemy.Draw(graphics);
            }
            else
            {
                foreach (Enemy enemy in this)
                    if (enemy.Active && enemy.Y < m_player.Y)
                        enemy.Draw(graphics);
            }
        }

        public Room Room
        {
            get { return m_room; }
        }
    }
}
